#ifndef DPICALCULATIONSERVICE_H
#define DPICALCULATIONSERVICE_H

#include <algorithm>

/**
 * DPICalculationService - 统一DPI计算服务
 * 
 * Martin Fowler重构：Extract Class
 * 将分散在PageRenderer和UnifiedPageRenderer中的DPI计算逻辑提取到统一服务中
 * 
 * 职责：
 * - 统一的A4尺寸计算
 * - 统一的毫米到像素转换
 * - 统一的DPI缩放计算
 * - 消除重复代码和不一致性
 */
class DPICalculationService
{
public:
    // A4纸张尺寸常量（毫米）
    static constexpr double A4_WIDTH_MM = 210.0;
    static constexpr double A4_HEIGHT_MM = 297.0;
    static constexpr double MM_PER_INCH = 25.4;

    /**
     * 统一的A4尺寸计算
     * @param dpi 目标DPI
     * @return A4尺寸（像素）
     */
    static inline int calculateA4Width(double dpi) {
        return static_cast<int>(A4_WIDTH_MM / MM_PER_INCH * dpi + 0.5);
    }
    
    static inline int calculateA4Height(double dpi) {
        return static_cast<int>(A4_HEIGHT_MM / MM_PER_INCH * dpi + 0.5);
    }
    
    /**
     * 统一的毫米到像素转换
     * @param mm 毫米值
     * @param dpi 目标DPI
     * @return 像素值
     */
    static inline int mmToPixels(double mm, double dpi) {
        return static_cast<int>(mm / MM_PER_INCH * dpi + 0.5);
    }
    
    /**
     * 统一的DPI缩放计算
     * @param sourceWidth 源宽度
     * @param sourceHeight 源高度
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 缩放比例
     */
    static inline double calculateScale(int sourceWidth, int sourceHeight, 
                                       int targetWidth, int targetHeight) {
        if (sourceWidth <= 0 || sourceHeight <= 0 || targetWidth <= 0 || targetHeight <= 0) {
            return 1.0;
        }
        
        double scaleX = static_cast<double>(targetWidth) / sourceWidth;
        double scaleY = static_cast<double>(targetHeight) / sourceHeight;
        return std::min(scaleX, scaleY);
    }
    
    /**
     * 检查DPI是否有效
     * @param dpi DPI值
     * @return 是否有效
     */
    static inline bool isValidDPI(double dpi) {
        return dpi > 0.0 && dpi <= 2400.0; // 合理的DPI范围
    }
    
    /**
     * 获取标准DPI值
     * @param dpi 输入DPI
     * @return 标准化后的DPI值
     */
    static inline double getStandardDPI(double dpi) {
        return isValidDPI(dpi) ? dpi : 150.0;
    }
};

#endif // DPICALCULATIONSERVICE_H